package org.ncibi.cytoscape.metscape.data;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.FilenameUtils;
import org.ncibi.cytoscape.metscape.file.DataFile;
import org.ncibi.cytoscape.metscape.file.ExcelFile;
import org.ncibi.cytoscape.metscape.file.TextFile;
import org.ncibi.cytoscape.metscape.utils.NumUtils;

public class CompoundData {
	
	private String[] columns = new String[0];
	private Map<String, Boolean> columnIsSigned = new HashMap<String, Boolean>();
	private Map<String, Double[]> compoundMap = new HashMap<String, Double[]>();
	private String name = "(none)";
	
	public static CompoundData parse(File compoundFile) {
		CompoundData ret = null;
		try {
			CompoundData ex = new CompoundData();
			DataFile base;
			if(compoundFile.getName().endsWith(".xls") || compoundFile.getName().endsWith(".xlsx"))
				base = new ExcelFile(compoundFile);
			else
				base = new TextFile(compoundFile);
			ex.name = FilenameUtils.removeExtension(compoundFile.getName());
			int startRow = base.getStartRowIndex();
			int endRow = base.getEndRowIndex();
			int endCol = 0;
			for(int i=1; i<=base.getEndColIndex(0); i++) {
				if(base.getString(0, i) == null) break;
				endCol++;
			}
			if(endCol > 0) {
				ex.columns = new String[endCol];
				for (int col = 1; col <= endCol; col++){
					String s = base.getString(0, col);
					ex.columns[col - 1] = s.trim();
					ex.columnIsSigned.put(s.trim(), false);
				}
			}
			// get remaining rows, the data
			startRow ++;
			for (int row = startRow; row < (endRow + 1); row++){
				String cid = base.getString(row, 0);
				if (cid == null) continue;
				cid = cid.trim().toUpperCase();
				Double[] data = new Double[endCol];
				for (int col = 1; col <= endCol; col++){
					data[col-1] = base.getDouble(row, col);
					if(data[col-1] != null && data[col-1] < 0) {
						ex.columnIsSigned.put(ex.columns[col-1], true);
					}
				}
				ex.addRecord(cid,data);
			}
			ret = ex;
		} catch (Throwable t) {
			t.printStackTrace();
		}
		return ret;
	}
	
	public static CompoundData parse(String compoundString) {
		CompoundData ret = null;
		try {
			CompoundData ex = new CompoundData();
			List<String> compounds = NumUtils.toUppercaseList(compoundString);
			for(String cid: compounds) {
				ex.addRecord(cid,null);
			}
			ret = ex;
		} catch (Throwable t) {
			t.printStackTrace();
		}
		return ret;
	}
	
	private void addRecord(String cid, Double[] data) {
		compoundMap.put(cid,data);
	}

	public Double[] getData(String cid) {
		return compoundMap.get(cid);
	}
	
	public String[] getColumns(){
		return columns;
	}
	
	public void setColumns(String[] columns) {
		this.columns = columns;
	}
	
	public Map<String, Boolean> getColumnIsSigned() {
		return columnIsSigned;
	}

	public void setColumnIsSigned(Map<String, Boolean> columnIsSigned) {
		this.columnIsSigned = columnIsSigned;
	}

	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public Map<String, Double[]> getCompoundMap() {
		return compoundMap;
	}

	public void setCompoundMap(Map<String, Double[]> compoundMap) {
		this.compoundMap = compoundMap;
	}
	
	public Set<String> idSet(){
		return compoundMap.keySet();
	}
	
	public boolean equals(Object o) {
		if(o instanceof CompoundData)
		{
			CompoundData other = (CompoundData) o;
			if(Arrays.equals(columns, other.getColumns())
					&& compoundMap.equals(other.getCompoundMap()) 
					&& name.equals(other.getName()))
				return true;
		}
		return false;
	}
	
	public boolean isEmpty(){
		if(compoundMap.isEmpty())
			return true;
		else
			return false;
	}
	
	public String toString() {
		return name;
	}
}
